import { vectorMeasure } from './initMap'
import { useMapStore } from '@/stores/map.js'
import { nextTick, toRefs } from 'vue'
// import { storeToRefs } from 'pinia'
// const { map } = storeToRefs(useMapStore())
const { map } = toRefs(useMapStore())
export const useTools = () => {
  var sketch //当前绘制的要素
  var measureTooltipElement //测量工具提示框对象
  var measureTooltip //测量工具中显示的测量
  var source //绘制的要素存放的位置
  var draw //定义画笔
  nextTick(() => {
    map.value.addLayer(vectorMeasure)
    source = map.value.getLayers().item(3).getSource()
  })
  /* ------------------------- 测量距离 ------------------------------ */
  const measureDistance = () => {
    map.value.getInteractions().pop() //移除绘制图形
    addInteraction('LineString') //添加绘图进行测量
    createMeasureTooltip() //创建测量工具提示框
  }
  /* ------------------------- 测量面积 ------------------------------ */
  const measureArea = () => {
    map.value.getInteractions().pop() //移除绘制图形
    addInteraction('Polygon') //添加绘图进行测量
    createMeasureTooltip() //创建测量工具提示框
  }
  /* ------------------------- 取消测量 ------------------------------ */
  const closeMeasure = () => {
    if (draw) {
      draw.setActive(false) //画笔失活
    }
  }
  /* ------------------------- 清除内容 ------------------------------ */
  const clearContent = () => {
    if (draw) {
      source.clear() // 清空数据源
      map.value.getOverlays().clear() //移除提示框
    }
  }
  /* ------------------------- 下载地图 ------------------------------ */
  const downloadMap = () => {
    map.value.once('postcompose', function (event) {
      const canvas = event.context.canvas
      canvas.toBlob(function (blob) {
        saveAs(blob, 'map.png')
      })
    })
    map.value.renderSync()
  }
  /**
   * 加载交互绘制控件函数
   */
  function addInteraction(type) {
    // 'Polygon' / 'LineString'
    draw = new ol.interaction.Draw({
      source: source, //测量绘制层数据源
      type, //几何图形类型
      /** @type {ol.geom.GeometryType} */
      style: new ol.style.Style({
        //绘制几何图形的样式
        fill: new ol.style.Fill({
          color: 'rgba(255, 255, 255, 0.2)'
        }),
        stroke: new ol.style.Stroke({
          color: 'rgba(0, 0, 0, 0.5)',
          lineDash: [10, 10],
          width: 2
        }),
        image: new ol.style.Circle({
          radius: 5,
          stroke: new ol.style.Stroke({
            color: 'rgba(0, 0, 0, 0.7)'
          }),
          fill: new ol.style.Fill({
            color: 'rgba(255, 255, 255, 0.2)'
          })
        })
      })
    })
    map.value.addInteraction(draw)
    var listener
    //绑定交互绘制工具开始绘制的事件
    draw.on(
      'drawstart',
      function (evt) {
        // set sketch
        sketch = evt.feature //绘制的要素

        /** @type {ol.Coordinate|undefined} */
        var tooltipCoord = evt.coordinate // 绘制的坐标
        //绑定change事件，根据绘制几何类型得到测量长度值或面积值，并将其设置到测量工具提示框中显示
        listener = sketch.getGeometry().on('change', function (evt) {
          var geom = evt.target //绘制几何要素
          var output
          if (geom instanceof ol.geom.Polygon) {
            output = formatArea(/** @type {ol.geom.Polygon} */ (geom)) //面积值
            tooltipCoord = geom.getInteriorPoint().getCoordinates() //坐标
          } else if (geom instanceof ol.geom.LineString) {
            output = formatLength(/** @type {ol.geom.LineString} */ (geom)) //长度值
            tooltipCoord = geom.getLastCoordinate() //坐标
          }
          measureTooltipElement.innerHTML = output //将测量值设置到测量工具提示框中显示
          measureTooltip.setPosition(tooltipCoord) //设置测量工具提示框的显示位置
        })
      },
      this
    )
    //绑定交互绘制工具结束绘制的事件
    draw.on(
      'drawend',
      function (evt) {
        measureTooltipElement.className = 'tooltip tooltip-static' //设置测量提示框的样式
        measureTooltip.setOffset([0, -7])
        // unset sketch
        sketch = null //置空当前绘制的要素对象
        // unset tooltip so that a new one can be created
        measureTooltipElement = null //置空测量工具提示框对象
        createMeasureTooltip() //重新创建一个测试工具提示框显示结果
        ol.Observable.unByKey(listener)
      },
      this
    )
  }
  /**
   *创建一个新的测量工具提示框（tooltip）
   */
  function createMeasureTooltip() {
    if (measureTooltipElement) {
      measureTooltipElement.parentNode.removeChild(measureTooltipElement)
    }
    measureTooltipElement = document.createElement('div')
    measureTooltipElement.className = 'tooltip tooltip-measure'
    measureTooltip = new ol.Overlay({
      element: measureTooltipElement,
      offset: [0, -15],
      positioning: 'bottom-center'
    })
    map.value.addOverlay(measureTooltip)
  }
  /**
   * 测量长度输出
   * @param {ol.geom.LineString} line
   * @return {string}
   */
  var formatLength = function (line) {
    var length
    var sphere = new ol.Sphere()
    //若使用测地学方法测量
    var sourceProj = map.value.getView().getProjection() //地图数据源投影坐标系
    length = sphere.getLength(line, {
      projection: sourceProj,
      radius: 6378137
    })
    var output
    if (length > 100) {
      output = Math.round((length / 1000) * 100) / 100 + ' ' + 'km' //换算成KM单位
    } else {
      output = Math.round(length * 100) / 100 + ' ' + 'm' //m为单位
    }
    return output //返回线的长度
  }
  /**
   * 测量面积输出
   * @param {ol.geom.Polygon} polygon
   * @return {string}
   */
  var formatArea = function (polygon) {
    var area
    var sphere = new ol.Sphere()
    //使用测地学方法测量
    var sourceProj = map.value.getView().getProjection() //地图数据源投影坐标系
    var geom = /** @type {ol.geom.Polygon} */ (polygon.clone().transform(sourceProj, 'EPSG:4326')) //将多边形要素坐标系投影为EPSG:4326
    area = Math.abs(sphere.getArea(geom, { projection: sourceProj, radius: 6378137 })) //获取面积

    var output
    if (area > 10000) {
      output = Math.round((area / 1000000) * 100) / 100 + ' ' + 'km<sup>2</sup>' //换算成KM单位
    } else {
      output = Math.round(area * 100) / 100 + ' ' + 'm<sup>2</sup>' //m为单位
    }
    return output //返回多边形的面积
  }
  return { measureDistance, measureArea, closeMeasure, clearContent, downloadMap }
}
